package com.newbee.model;

import com.alibaba.fastjson.JSONArray;
import com.newbee.enums.TraceNodeEnum;
import lombok.Data;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.index.Indexed;
import org.springframework.data.mongodb.core.mapping.Document;

import java.util.Date;
import java.util.concurrent.CopyOnWriteArrayList;

/**
 * 链路节点对象：每个根节点（A/D）对应Mongo中的一条记录，包含完整子树
 * 假设链路：A——>B, B——>C, B-->D, D——>E, E——>F
 */
@Data
@Document(collection = "trace_node")
public class TraceNode {

    // 仅用于映射MongoDB自动生成的_id，无需手动维护
    @Id
    private String id;

    // 节点ID
    @Indexed
    private String nodeId;

    // 业务唯一traceId
    @Indexed
    private String traceId;

    // 节点状态（PENDING/RUNNING/SUCCESS/FAIL）
    private TraceNodeEnum status;

    // 类名
    private String className;

    // 方法名（如"aMethod"）
    private String methodName;

    // 脱敏入参
    private JSONArray requestParam;

    // 脱敏出参
    private JSONArray responseParam;

    // 执行耗时（毫秒）
    private Long costTime;

    // 耗时预警阈值（单位：毫秒，用于判断是否超时）
    private long warnThreshold;

    // 节点创建时间
    private Date createTime;

    // 节点更新时间
    private Date updateTime;

    // 子节点列表（嵌套存储同步调用的子节点）
    // 解决多线程添加子节点并发安全问题, 适合异步线程少的情况下
    private CopyOnWriteArrayList<TraceNode> children;

    // 异常堆栈（失败时存储）
    private String exceptionStack;

    // 当前节点是不是异步触发的, 假设 A异步调用B,B异步调用C, 那么 B是异步调用触发, C 不是
    private boolean async;

    public String getMethodPath() {
        return className + "." + methodName;
    }
}
